<template>
  <div></div>
</template>

<script>
import * as THREE from 'three'
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min'

export default {
  name: 'ThirteenSix',
  data() {
    return {
      cylinder: null,                   // 圆柱体对象
    }
  },
  mounted() {
    this.initScene();
    this.initCamera();
    this.initRenderer();
    this.addCylinderGeometry(2, 2, 4, 8, 4, true, 0, Math.PI * 2);
    this.addOrbitControls();
    this.animation();
    this.initControl();
  },
  methods: {
    // 初始化场景
    initScene() {
      this.scene = new THREE.Scene();
    },
    // 初始化相机
    initCamera() {
      // 创建一个相机 视点
      this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
      // 设置相机的位置
      this.camera.position.x = 0;
      this.camera.position.y = 0;
      this.camera.position.z = 8;
      this.camera.lookAt(0, 0, 0);
    },
    // 初始化渲染器
    initRenderer() {
      // 创建一个渲染器
      this.renderer = new THREE.WebGLRenderer();
      // 设置渲染器尺寸
      this.renderer.setSize(window.innerWidth, window.innerHeight);
      document.body.appendChild(this.renderer.domElement);
    },
    // 添加一个圆柱体
    addCylinderGeometry(radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2) {
      const cylinderGeometry = new THREE.CylinderGeometry(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength);
      const cylinderMaterial = new THREE.MeshBasicMaterial({ color: 0x00ffff });
      cylinderMaterial.side = THREE.DoubleSide;
      cylinderMaterial.wireframe = true;
      this.cylinder = new THREE.Mesh(cylinderGeometry, cylinderMaterial);
      this.scene.add(this.cylinder);
    },
    // 添加轨道控制器
    addOrbitControls() {
      this.orbitControls = new OrbitControls(this.camera, this.renderer.domElement);
      // 设置带阻尼的惯性
      this.orbitControls.enableDamping = true;
      // 设置阻尼系数
      this.orbitControls.dampingFactor = 0.05;
    },
    // 动画函数
    animation() {
      this.orbitControls.update();
      // 渲染
      this.renderer.render(this.scene, this.camera);
      requestAnimationFrame(this.animation);
    },
    // 初始化lil.gui调试工具
    initControl() {
      const gui = new GUI();

      const params = {
        radiusTop: this.cylinder.geometry.parameters.radiusTop,
        radiusBottom: this.cylinder.geometry.parameters.radiusBottom,
        height: this.cylinder.geometry.parameters.height,
        radialSegments: this.cylinder.geometry.parameters.radialSegments,
        heightSegments: this.cylinder.geometry.parameters.heightSegments,
        openEnded: this.cylinder.geometry.parameters.openEnded,
        thetaStart: this.cylinder.geometry.parameters.thetaStart,
        thetaLength: this.cylinder.geometry.parameters.thetaLength,
      }

      let folder = gui.addFolder('圆柱体属性');
      folder.add(params, 'radiusTop', -3, 10).step(0.1).name('radiusTop-顶部半径').onChange(radius => {
        params.radius = radius;
        this.scene.remove(this.cylinder);
        this.addCylinderGeometry(params.radiusTop, params.radiusBottom, params.height, params.radialSegments, params.heightSegments, params.openEnded, params.thetaStart, params.thetaLength);
      });
      folder.add(params, 'radiusBottom', -3, 10).step(0.1).name('radiusTop-底部半径').onChange(radiusBottom => {
        params.radiusBottom = radiusBottom;
        this.scene.remove(this.cylinder);
        this.addCylinderGeometry(params.radiusTop, params.radiusBottom, params.height, params.radialSegments, params.heightSegments, params.openEnded, params.thetaStart, params.thetaLength);
      });
      folder.add(params, 'height', 0, 10).step(0.1).name('height-高度').onChange(height => {
        params.height = height;
        this.scene.remove(this.cylinder);
        this.addCylinderGeometry(params.radiusTop, params.radiusBottom, params.height, params.radialSegments, params.heightSegments, params.openEnded, params.thetaStart, params.thetaLength);
      });
      folder.add(params, 'radialSegments', 0, 50).step(1).name('radialSegments-水平分段数').onChange(radialSegments => {
        params.radialSegments = radialSegments;
        this.scene.remove(this.cylinder);
        this.addCylinderGeometry(params.radiusTop, params.radiusBottom, params.height, params.radialSegments, params.heightSegments, params.openEnded, params.thetaStart, params.thetaLength);
      });
      folder.add(params, 'heightSegments', 0, 50).step(1).name('heightSegments-垂直分段数').onChange(heightSegments => {
        params.heightSegments = heightSegments;
        this.scene.remove(this.cylinder);
        this.addCylinderGeometry(params.radiusTop, params.radiusBottom, params.height, params.radialSegments, params.heightSegments, params.openEnded, params.thetaStart, params.thetaLength);
      });
      folder.add(params, 'openEnded').name('openEnded-开放还是封顶').onChange(openEnded => {
        params.openEnded = openEnded;
        this.scene.remove(this.cylinder);
        this.addCylinderGeometry(params.radiusTop, params.radiusBottom, params.height, params.radialSegments, params.heightSegments, params.openEnded, params.thetaStart, params.thetaLength);
      });
      folder.add(params, 'thetaStart', 0, 5).step(0.1).name('thetaStart-起始角度').onChange(thetaStart => {
        params.thetaStart = thetaStart;
        this.scene.remove(this.cylinder);
        this.addCylinderGeometry(params.radiusTop, params.radiusBottom, params.height, params.radialSegments, params.heightSegments, params.openEnded, params.thetaStart, params.thetaLength);
      });
      folder.add(params, 'thetaLength', 0, 2 * Math.PI).step(0.1).name('thetaLength-覆盖角度').onChange(thetaLength => {
        params.thetaLength = thetaLength;
        this.scene.remove(this.cylinder);
        this.addCylinderGeometry(params.radiusTop, params.radiusBottom, params.height, params.radialSegments, params.heightSegments, params.openEnded, params.thetaStart, params.thetaLength);
      });
    }
  }
}
</script>

<style scoped>

</style>
